package com.uni.sofia.reader.presentation
{
	import com.uni.sofia.reader.magazine.Magazine;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.collections.ArrayCollection;
	import mx.collections.Sort;
	import mx.collections.SortField;
	
	/**
	 * Model class responsible for the content of magazines list
	 */ 
	public class LibraryPresentation extends EventDispatcher
	{
		
		[ArrayElementType("Magazine")]
		private var _magazines:ArrayCollection = new ArrayCollection();
		
		[Bindable(Event="magazinesChanged")]
		/**
		 * The list of magazines
		 */ 
		public function get magazines():ArrayCollection
		{
			return _magazines;
		}
		
		public function set magazines(value:ArrayCollection):void
		{
			_magazines = value;
			dispatchEvent(new Event("magazinesChanged"));			
		}
		
		[Bindable(Event="magazinesChanged")]
		/**
		 * the list of unique publishers of magazines 
		 */ 
		public function get publishers():ArrayCollection
		{
			var publishers:ArrayCollection = new ArrayCollection();
			for(var i:int = 0; i < magazines.source.length; i++)
			{
				if(!publishers.contains(Magazine(magazines.source[i]).publisher))
					publishers.addItem(Magazine(magazines.source[i]).publisher);
			}
			return publishers;
		}
		
		/**
		 * Adds a magazine to the magazines list
		 * @param magazine
		 * 	magazine to be added
		 */ 
		public function addMagazine(magazine:Magazine):void
		{
			magazines.addItem(magazine);
			dispatchEvent(new Event("magazinesChanged"));
		}
		
		
		/**
		 * Sorts all magazines by date of release starting with the oldest ones
		 */ 
		public function sortByDate():void
		{
			var sort:Sort = new Sort();
			sort.fields = [new SortField("released")]; 
			magazines.sort = sort;
			magazines.refresh();
			dispatchEvent(new Event("magazinesChanged"));
		}
		
		/**
		 * Sorts all magazines by publisher - alphabetically
		 */ 
		public function sortByPulisher():void
		{
			var sort:Sort = new Sort();
			sort.fields = [new SortField("publisher")]; 
			magazines.sort = sort;
			magazines.refresh();
			dispatchEvent(new Event("magazinesChanged"));
		}
		
		/**
		 * Sorts all magazines alphabetically
		 */ 
		public function sortByName():void
		{
			var sort:Sort = new Sort();
			sort.fields = [new SortField("name")]; 
			magazines.sort = sort;
			magazines.refresh();	
			dispatchEvent(new Event("magazinesChanged"));
		}
		
		/**
		 * Sorts all magazines by their length, starting with the bigest one
		 */ 
		public function sortBySizeDescending():void
		{
			//var sort:Sort = new Sort();
			//sort.fields = [new SortField("name")]; 
			//magazines.sort = sort;
			//magazines.refresh();	
		}
		
		/**
		 * Sets the publisher filter of the magazines
		 * @param filter
		 * 		the array of all permited publishers whom magazines will be shown 
		 */ 
		public function setFilter(filter:Array):void
		{
			
			magazines.filterFunction = publisherFilterFunction;
			
			function publisherFilterFunction(obj:Object):Boolean
			{
				var magazine:Magazine = Magazine(obj);
				for(var i:int = 0; i < filter.length; i++)
				{
					if(magazine.publisher == filter[i] as String)
					{
						return true;
					}
				}
				return false;
			}	
			magazines.refresh();
			dispatchEvent(new Event("magazinesChanged"));
		}
		/**
		 * The filter of shown publishers
		 */ 
		public var filter:Array = [];
		
		/**
		 *This function updates the filter for publishers
		 * @param value
		 * 		the new publisher to be updated
		 * @param checked
		 * 		if true, the publisher must be added, otherwise the publisher must be removed from the filter 
		 */ 
		public function updateFilter(value:String, checked:Boolean):void
		{
			var arrColl:ArrayCollection = new ArrayCollection(filter);
			
			if((arrColl.contains(value) && checked) || (!arrColl.contains(value) && !checked))
			{
				//do nothing
			}
			else if (arrColl.contains(value) && !checked)
			{
				var indexToRemove:int = -1;
				for(var i:int = 0; i < arrColl.length; i++)
				{
					if(value == arrColl.getItemAt(i))
					{
						indexToRemove = i;
					}
				}
				arrColl.removeItemAt(indexToRemove);
			}
			else
			{
				arrColl.addItem(value);
			}
			
			filter = arrColl.source;
		}
		
	}
}